<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>明暗主题切换示例</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <style>
        /* 自定义过渡动画，确保主题切换时的平滑效果 */
        :root {
            --transition-speed: 0.3s;
        }

        * {
            transition: background-color var(--transition-speed) ease,
            color var(--transition-speed) ease,
            border-color var(--transition-speed) ease,
            box-shadow var(--transition-speed) ease;
        }

        /* 防止图片在主题切换时闪烁 */
        img {
            transition: none;
        }

        /* 主题切换按钮的旋转动画 */
        .theme-toggle-icon {
            transition: transform var(--transition-speed) ease;
        }

        .dark .theme-toggle-icon {
            transform: rotate(180deg);
        }
    </style>
</head>
<body class="bg-white text-gray-900 dark:bg-gray-900 dark:text-white min-h-screen">
<!-- 主题切换按钮 -->
<div class="fixed top-4 right-4 z-50">
    <button id="theme-toggle"
            class="p-3 rounded-full bg-gray-200 dark:bg-gray-700 shadow-lg hover:shadow-xl transition-all duration-300 focus:outline-none focus:ring-2 focus:ring-blue-500">
        <!-- 太阳图标（白天模式） -->
        <svg id="sun-icon" class="theme-toggle-icon w-6 h-6 text-yellow-500" fill="currentColor" viewBox="0 0 20 20">
            <path fill-rule="evenodd" d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z" clip-rule="evenodd"></path>
        </svg>
    </button>
</div>

<!-- 主要内容区域 -->
<div class="container mx-auto px-4 py-12">
    <!-- 标题区域 -->
    <div class="text-center mb-16">
        <h1 class="text-4xl md:text-6xl font-bold mb-6 bg-gradient-to-r from-blue-600 to-purple-600 dark:from-blue-400 dark:to-purple-400 bg-clip-text text-transparent">
            明暗主题切换
        </h1>
        <p class="text-xl text-gray-600 dark:text-gray-300 max-w-2xl mx-auto">
            一个美观且功能完整的主题切换示例，支持系统偏好自动检测
        </p>
    </div>

    <!-- 卡片网格 -->
    <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 mb-16">
        <!-- 卡片1 -->
        <div class="bg-white dark:bg-gray-800 rounded-2xl shadow-lg hover:shadow-xl transition-all duration-300 p-6 border border-gray-200 dark:border-gray-700">
            <div class="w-12 h-12 rounded-lg bg-blue-100 dark:bg-blue-900 flex items-center justify-center mb-4">
                <svg class="w-6 h-6 text-blue-600 dark:text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path>
                </svg>
            </div>
            <h3 class="text-xl font-semibold mb-2">快速切换</h3>
            <p class="text-gray-600 dark:text-gray-300">
                一键切换明暗主题，界面元素平滑过渡，无闪烁现象
            </p>
        </div>

        <!-- 卡片2 -->
        <div class="bg-white dark:bg-gray-800 rounded-2xl shadow-lg hover:shadow-xl transition-all duration-300 p-6 border border-gray-200 dark:border-gray-700">
            <div class="w-12 h-12 rounded-lg bg-green-100 dark:bg-green-900 flex items-center justify-center mb-4">
                <svg class="w-6 h-6 text-green-600 dark:text-green-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"></path>
                </svg>
            </div>
            <h3 class="text-xl font-semibold mb-2">系统集成</h3>
            <p class="text-gray-600 dark:text-gray-300">
                自动检测系统主题偏好，智能切换默认主题
            </p>
        </div>

        <!-- 卡片3 -->
        <div class="bg-white dark:bg-gray-800 rounded-2xl shadow-lg hover:shadow-xl transition-all duration-300 p-6 border border-gray-200 dark:border-gray-700">
            <div class="w-12 h-12 rounded-lg bg-purple-100 dark:bg-purple-900 flex items-center justify-center mb-4">
                <svg class="w-6 h-6 text-purple-600 dark:text-purple-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4m0 5c0 2.21-3.582 4-8 4s-8-1.79-8-4"></path>
                </svg>
            </div>
            <h3 class="text-xl font-semibold mb-2">持久化存储</h3>
            <p class="text-gray-600 dark:text-gray-300">
                主题选择自动保存，下次访问时保持用户偏好
            </p>
        </div>
    </div>

    <!-- 表单示例 -->
    <div class="max-w-2xl mx-auto bg-white dark:bg-gray-800 rounded-2xl shadow-lg p-8 border border-gray-200 dark:border-gray-700">
        <h2 class="text-2xl font-bold mb-6">交互元素演示</h2>

        <div class="space-y-6">
            <div>
                <label class="block text-sm font-medium mb-2 text-gray-700 dark:text-gray-300">输入框</label>
                <input type="text"
                       class="w-full px-4 py-3 bg-gray-50 dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none transition-all"
                       placeholder="请输入内容...">
            </div>

            <div>
                <label class="block text-sm font-medium mb-2 text-gray-700 dark:text-gray-300">选择框</label>
                <select class="w-full px-4 py-3 bg-gray-50 dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none transition-all">
                    <option>选项一</option>
                    <option>选项二</option>
                    <option>选项三</option>
                </select>
            </div>

            <div class="flex items-center">
                <input type="checkbox" id="checkbox" class="w-5 h-5 text-blue-600 bg-gray-100 dark:bg-gray-700 border-gray-300 dark:border-gray-600 rounded focus:ring-blue-500 focus:ring-2">
                <label for="checkbox" class="ml-2 text-sm font-medium text-gray-700 dark:text-gray-300">同意用户协议</label>
            </div>

            <button class="w-full bg-blue-600 hover:bg-blue-700 text-white font-medium py-3 px-4 rounded-lg transition-all duration-300 transform hover:scale-[1.02] focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 dark:focus:ring-offset-gray-800">
                提交表单
            </button>
        </div>
    </div>

    <!-- 页脚 -->
    <div class="text-center mt-16 pt-8 border-t border-gray-200 dark:border-gray-700">
        <p class="text-gray-600 dark:text-gray-400">
            © 2023 明暗主题切换示例. 所有元素均支持主题切换无闪烁.
        </p>
    </div>
</div>

<script>
    /**
     * 明暗主题切换实现原理说明：
     *
     * 1. CSS 类控制：
     *    - 使用 Tailwind CSS 的 dark: 前缀来定义暗色主题样式
     *    - 通过在 <html> 或 <body> 元素上添加/移除 'dark' 类来切换主题
     *
     * 2. 状态管理：
     *    - 使用 localStorage 存储用户主题偏好
     *    - 检测系统主题偏好 (prefers-color-scheme)
     *    - 提供三种模式：浅色、深色、自动
     *
     * 3. 无闪烁实现：
     *    - 在页面加载早期就设置主题类（在DOMContentLoaded之前）
     *    - 使用CSS过渡动画确保平滑切换
     *    - 避免在JavaScript执行期间出现样式重绘
     */

        // 主题管理器对象
    const ThemeManager = {
            // 当前主题状态
            currentTheme: 'auto',

            // 初始化主题
            init() {
                // 从localStorage获取保存的主题设置
                const savedTheme = localStorage.getItem('theme');
                if (savedTheme) {
                    this.currentTheme = savedTheme;
                }

                // 应用主题
                this.applyTheme();

                // 监听系统主题变化
                window.matchMedia('(prefers-color-scheme: dark)')
                    .addEventListener('change', () => {
                        if (this.currentTheme === 'auto') {
                            this.applyTheme();
                        }
                    });
            },

            // 切换主题
            toggleTheme() {
                if (this.currentTheme === 'dark') {
                    this.currentTheme = 'light';
                } else if (this.currentTheme === 'light') {
                    this.currentTheme = 'auto';
                } else {
                    this.currentTheme = 'dark';
                }

                // 保存到localStorage
                localStorage.setItem('theme', this.currentTheme);

                // 应用新主题
                this.applyTheme();
            },

            // 应用主题到页面
            applyTheme() {
                const htmlElement = document.documentElement;

                // 根据当前主题设置决定是否添加dark类
                if (this.currentTheme === 'dark' ||
                    (this.currentTheme === 'auto' &&
                        window.matchMedia('(prefers-color-scheme: dark)').matches)) {
                    htmlElement.classList.add('dark');
                } else {
                    htmlElement.classList.remove('dark');
                }
            }
        };

    // 页面加载完成后初始化
    document.addEventListener('DOMContentLoaded', () => {
        // 初始化主题管理器
        ThemeManager.init();

        // 绑定主题切换按钮事件
        const themeToggle = document.getElementById('theme-toggle');
        themeToggle.addEventListener('click', () => {
            ThemeManager.toggleTheme();
        });
    });

    /**
     * 关键实现细节和注意事项：
     *
     * 1. 防止闪烁的关键技术点：
     *    - 在HTML头部尽早初始化主题（通过内联脚本）
     *    - 使用CSS过渡而不是JavaScript动画
     *    - 避免在主题切换时重新计算样式
     *
     * 2. CSS过渡优化：
     *    - 为所有可能变化的属性设置过渡动画
     *    - 使用适当的过渡时间和缓动函数
     *    - 排除图片等不需要过渡的元素
     *
     * 3. 系统集成：
     *    - 监听系统主题偏好变化
     *    - 提供"自动"模式以跟随系统设置
     *    - 使用localStorage持久化用户选择
     *
     * 4. 可访问性考虑：
     *    - 确保足够的对比度在两种主题下
     *    - 保持焦点状态的可见性
     *    - 支持键盘导航
     */
</script>
</body>
</html>